import React, { useState, useCallback, useEffect } from 'react';
import { useParams } from 'react-router-dom';

const NodeType = {
  START: 'start',
  END: 'end',
  DEFAULT: 'default'
};

interface NodeType {
  id: string;
  type: string;
  x: number;
  y: number;
  name?: string;
}

const initialNodes = [
  { id: 'start', type: NodeType.START, x: 100, y: 100, name: 'Start' },
  { id: 'end', type: NodeType.END, x: 100, y: 300, name: 'End' }
];

interface DraggingState {
  id: string;
  isControlPoint: boolean;
  offsetX: number;
  offsetY: number;
}

interface Connection {
  id: string;
  source: string;
  target: string;
  waypoints: { x: number; y: number }[];
}

const FlowEditor = () => {
  const { id } = useParams<{ id?: string }>();
  const [nodes, setNodes] = useState<NodeType[]>([]);
  const [connections, setConnections] = useState<Connection[]>([]);
  const [dragging, setDragging] = useState<DraggingState | null>(null);
  const [newNodeType, setNewNodeType] = useState(NodeType.DEFAULT);
  const [editingNodeId, setEditingNodeId] = useState<string | null>(null);
  const [tempName, setTempName] = useState('');
  const [selectedNodeId, setSelectedNodeId] = useState<string | null>(null);
  const [hoveredConnectionId, setHoveredConnectionId] = useState<string | null>(null);

  // 新增数据加载效果
  useEffect(() => {
    if (!id) {
      setNodes(initialNodes);
      return;
    }

    const fetchWorkflow = async () => {
      try {
        const response = await fetch(`/api/workflow-info/${id}`);
        const data = await response.json();
        
        // 转换后端数据到前端节点格式
        const convertedNodes = data.nodes.map((node: any) => ({
          id: node.nodeId,
          type: node.type || NodeType.DEFAULT,
          x: node.position.x,
          y: node.position.y,
          name: node.name
        }));

        // 转换连接数据
        const convertedConnections = data.connections.map((conn: any) => ({
          id: conn.connectionId,
          source: conn.sourceId,
          target: conn.targetId,
          waypoints: conn.waypoints || []
        }));

        setNodes(convertedNodes);
        setConnections(convertedConnections);
      } catch (error) {
        console.error('Failed to load workflow:', error);
        // 可以添加错误处理逻辑
      }
    };

    fetchWorkflow();
  }, [id]);

  // 处理节点拖拽
  const handleMouseDown = (id: string) => (e: React.MouseEvent) => {
    if (e.target === e.currentTarget) {
      const rect = e.currentTarget.getBoundingClientRect();
      setDragging({
        id,
        isControlPoint: false,
        offsetX: e.clientX - rect.left,  // 使用绝对坐标计算
        offsetY: e.clientY - rect.top
      });
    }
  };

  const handleMouseMove = useCallback((e: React.MouseEvent) => {
    if (!dragging) return;
    
    setNodes(nodes =>
      nodes.map(node => 
        node.id === dragging.id
          ? { 
              ...node, 
              x: e.clientX - dragging.offsetX,
              y: e.clientY - dragging.offsetY
            }
          : node
      )
    );
  }, [dragging]);

  const handleMouseUp = () => {
    setDragging(null);
  };

  // 添加新节点
  const addNode = () => {
    const newNode = {
      id: `node_${Date.now()}`,
      type: newNodeType,
      x: 300,
      y: 200,
      name: 'New Node'
    };
    setNodes([...nodes, newNode]);
  };

  // 新增节点点击处理
  const handleNodeClick = (nodeId: string) => {
    const clickedNode = nodes.find(n => n.id === nodeId);
    if (!clickedNode) return;

    if (!selectedNodeId) {
      // 禁止选择END节点作为起始节点
      if (clickedNode.type === NodeType.END) return;
      setSelectedNodeId(nodeId);
    } else if (selectedNodeId !== nodeId) {
      // 禁止选择START节点作为目标节点
      const sourceNode = nodes.find(n => n.id === selectedNodeId)!;
      if (sourceNode.type !== NodeType.START || clickedNode.type !== NodeType.END) {
        createConnection(selectedNodeId, nodeId);
      }
      setSelectedNodeId(null);
    } else {
      setSelectedNodeId(null);
    }
  };

  // 修改后的计算路径方法（直接返回起点终点）
  const calculateWaypoints = (source: typeof nodes[0], target: typeof nodes[0]) => {
    const start = getEdgePoint(source, target, true);
    const end = getEdgePoint(target, source, false);
    return [start, end]; // 直接返回起点和终点，形成直线
  };

  // 修改后的创建连接方法
  const createConnection = (sourceId: string, targetId: string) => {
    // 验证是否已存在相同连接
    const exists = connections.some(conn => 
      (conn.source === sourceId && conn.target === targetId) ||
      (conn.source === targetId && conn.target === sourceId)
    );
    
    if (exists || sourceId === targetId) return;

    const sourceNode = nodes.find(n => n.id === sourceId)!;
    const targetNode = nodes.find(n => n.id === targetId)!;
    
    // 新增连接规则验证
    if (sourceNode.type === NodeType.END ||   // END节点不能作为源
        targetNode.type === NodeType.START || // START节点不能作为目标
        (sourceNode.type === NodeType.START && targetNode.type === NodeType.END)) { // 直接连接START和END
      return;
    }

    const newConnection = {
      id: `conn_${Date.now()}`,
      source: sourceId,
      target: targetId,
      waypoints: calculateWaypoints(sourceNode, targetNode)
    };
    
    setConnections([...connections, newConnection]);
  };

  // 计算不同形状节点的连接点
  const getEdgePoint = (node: typeof nodes[0], targetNode: typeof nodes[0], isSource: boolean) => {
    const isCircle = node.type !== NodeType.DEFAULT;
    const nodeCenterX = node.x + (isCircle ? 20 : 40); // 圆形节点半径20，矩形宽度80
    const nodeCenterY = node.y + 20; // 所有节点高度40
    
    if (isCircle) {
      const dx = targetNode.x - node.x;
      const dy = targetNode.y - node.y;
      const angle = Math.atan2(dy, dx);
      return {
        x: nodeCenterX + Math.cos(angle) * 20,
        y: nodeCenterY + Math.sin(angle) * 20
      };
    }
    
    // 矩形节点处理
    const targetIsRight = targetNode.x > node.x;
    return {
      x: node.x + (targetIsRight ? 80 : 0),
      y: nodeCenterY
    };
  };

  // 处理名称点击
  const handleNameClick = (node: NodeType) => {
    setEditingNodeId(node.id);
    setTempName(node.name || '');
  };

  // 保存名称修改
  const saveName = (nodeId: string) => {
    setNodes(nodes =>
      nodes.map(node =>
        node.id === nodeId ? { ...node, name: tempName } : node
      )
    );
    setEditingNodeId(null);
  };

  // 新增删除连接方法
  const deleteConnection = (connectionId: string) => {
    setConnections(connections.filter(conn => conn.id !== connectionId));
  };

  return (
    <div 
      style={{ position: 'relative', height: '600px', border: '1px solid #ccc' }}
      onMouseMove={handleMouseMove}
      onMouseUp={handleMouseUp}
      onClick={() => setSelectedNodeId(null)}
    >
      {/* Connections */}
      <svg style={{ position: 'absolute', width: '100%', height: '100%' }}>
        {connections.map(conn => {
          const sourceNode = nodes.find(n => n.id === conn.source)!;
          const targetNode = nodes.find(n => n.id === conn.target)!;
          
          const start = getEdgePoint(sourceNode, targetNode, true);
          const end = getEdgePoint(targetNode, sourceNode, false);
          // 计算中点坐标
          const midX = (start.x + end.x) / 2;
          const midY = (start.y + end.y) / 2;

          return (
            <g 
              key={conn.id}
              onMouseEnter={() => setHoveredConnectionId(conn.id)}
              onMouseLeave={() => setHoveredConnectionId(null)}
            >
              {/* 半透明点击区域 */}
              <path
                d={`M ${start.x} ${start.y} L ${end.x} ${end.y}`}
                stroke="transparent"
                strokeWidth="20"
                fill="none"
                onClick={(e) => {
                  e.stopPropagation();
                  deleteConnection(conn.id);
                }}
              />
              {/* 实际连接线 */}
              <path
                d={`M ${start.x} ${start.y} L ${end.x} ${end.y}`}
                stroke="#666"
                strokeWidth="2"
                fill="none"
                markerEnd="url(#arrowhead)"
              />
              {/* 删除按钮 */}
              {hoveredConnectionId === conn.id && (
                <g 
                  transform={`translate(${midX - 10},${midY - 10})`}
                  onClick={(e) => {
                    e.stopPropagation();
                    deleteConnection(conn.id);
                  }}
                  style={{ cursor: 'pointer' }}
                >
                  <circle cx="10" cy="10" r="12" fill="#fff" stroke="#ccc" />
                  <path 
                    d="M6 6L14 14M14 6L6 14" 
                    stroke="#ff4444" 
                    strokeWidth="2"
                  />
                  <path
                    d="M8 10h4"
                    stroke="#ff4444"
                    strokeWidth="2"
                  />
                </g>
              )}
            </g>
          );
        })}
        <defs>
          <marker
            id="arrowhead"
            markerWidth="18"
            markerHeight="18"
            refX="16"
            refY="9"
            orient="auto"
          >
            <path 
              d="M2,2 L16,9 L2,16 L6,9 Z" 
              fill="#333"
              stroke="#333"
              strokeWidth="1"
            />
          </marker>
        </defs>
      </svg>

      {/* Nodes */}
      {nodes.map(node => (
        <div
          key={node.id}
          style={{
            position: 'absolute',
            left: node.x,
            top: node.y,
            width: node.type === NodeType.DEFAULT ? '80px' : '40px',
            height: '40px',
            borderRadius: node.type === NodeType.DEFAULT ? '8px' : '50%',
            background: node.type === NodeType.START ? '#4CAF50' : 
                       node.type === NodeType.END ? '#F44336' : '#2196F3',
            cursor: 'move',
            display: 'flex',
            flexDirection: 'column',
            alignItems: 'center',
            justifyContent: 'center',
            color: 'white',
            boxShadow: '0 2px 5px rgba(0,0,0,0.2)',
            padding: '5px',
            border: selectedNodeId === node.id ? '2px solid yellow' : 'none',
          }}
          onMouseDown={handleMouseDown(node.id)}
          onClick={(e) => {
            e.stopPropagation();
            handleNodeClick(node.id);
          }}
        >
          {editingNodeId === node.id ? (
            <input
              type="text"
              value={tempName}
              onChange={(e) => setTempName(e.target.value)}
              onBlur={() => saveName(node.id)}
              onKeyPress={(e) => e.key === 'Enter' && saveName(node.id)}
              style={{
                width: '100%',
                background: 'transparent',
                border: 'none',
                color: 'white',
                textAlign: 'center',
                outline: 'none'
              }}
              autoFocus
            />
          ) : (
            <div 
              onClick={() => handleNameClick(node)}
              style={{
                cursor: 'text',
                fontSize: '12px',
                padding: '2px',
                width: '100%',
                textAlign: 'center'
              }}
            >
              {node.name}
            </div>
          )}

          <div style={{
            position: 'absolute',
            bottom: '-25px',
            left: '50%',
            transform: 'translateX(-50%)',
            fontSize: '10px',
            color: '#666'
          }}>
            Drag to connect
          </div>
        </div>
      ))}

      {/* Controls */}
      <div style={{ position: 'absolute', top: '10px', left: '10px' }}>
        <select 
          value={newNodeType} 
          onChange={(e) => setNewNodeType(e.target.value)}
        >
          <option value={NodeType.DEFAULT}>Default Node</option>
          <option value={NodeType.START}>Start Node</option>
          <option value={NodeType.END}>End Node</option>
        </select>
        <button onClick={addNode}>Add Node</button>
      </div>
    </div>
  );
};

export default FlowEditor;